#include"Air.h" 

USING_NS_CC;

void Fire::initFire(){
	//setTexture(Director::getInstance()->getTextureCache()->addImage("Air(big).png"));
	setLife(1);
	//setLifeVar(0.005);
	setSpeed(1);
	setSpeedVar(3);
	//setPosVar(Point(0, 0));
	setStartColor(Color4F(1, 0.5, 0, 1));
	setStartColorVar(Color4F(0, 0, 0, 0));
	setEndColor(Color4F(1, 0, 0, 0));
	setEndColorVar(Color4F(0, 0, 0, 0));
	//setEndSize(_startSize / 2);
	setTotalParticles(200);
	//setGravity(Point(0, 0));
	setPositionType(ParticleSystem::PositionType::RELATIVE);
}

bool Fire::init(){
	if (!ParticleSun::init()){
		return false;
	}
	initFire();
	return true;
}

void Fire::update(float dt){


	Air* parentAir = ((Air*)(this->getParent()));
	setPosition(bindSprite->getPosition() - this->getParent()->getPosition());
	setEmissionRate(this->getContactParticleNumber()*5);
	ParticleSun::update(dt);
}

long Fire::getContactParticleNumber(){
	long result = 0;
	for (std::pair<int, long> contactNum : contactParticle){
		result += contactNum.second;
	}
	return result;
}

void AirPartle::initAir(){

	setTexture(Director::getInstance()->getTextureCache()->addImage("air(big).png"));
	setStartSize(70);
	setStartSizeVar(30);
	setEndSize(250);
	setPosVar(Point(2, 2));
	setTotalParticles(3000);
	setStartColor(Color4F(1, 1, 1, 0.3));
	setEndColor(Color4F(1, 1, 1, 0));
	setSpeed(20);
	setSpeedVar(20);
	setLife(3);
	setLifeVar(1);
	setEmissionRate(getTotalParticles() / getLife() / 40);
	setBlendAdditive(false);
	this->setAutoRemoveOnFinish(true);
	setPositionType(ParticleSystem::PositionType::RELATIVE);
}

bool AirPartle::init(){
	if (!ParticleSun::init()){
		return false;
	}
	return true;
}


void AirPartle::updateQuadWithParticle(tParticle* particle, const Point& newPosition){
	if (!this->isVisible()) return;
	Air* parentAir = ((Air*)(this->getParent()));
	parentAir->check(airID, newPosition + this->getPosition(), particle->size);
	ParticleSun::updateQuadWithParticle(particle, newPosition);
}

bool AirPartle::addParticle(){
	if (!ParticleSun::addParticle())
		return false;
	//Air* parentAir = ((Air*)(this->getParent()));
	//tParticle * particle = &_particles[_particleCount - 1];
	//parentAir->check(airID, particle->pos + this->getPosition(), particle->size);

	return true;

}

void AirPartle::update(float dt){
	Air* parentAir = ((Air*)(this->getParent()));
	while (moveSpeed > 0){
		setPosition(getPosition() + Posbridge);
		addParticle();
		moveSpeed--;
	}
	//parentAir->clearCrash();
	parentAir->resetAir(airID);

	ParticleSun::update(dt);
}

void Air::setTouchLayer(Layer* _layer){

	auto airReleaseListener = EventListenerTouchAllAtOnce::create();
	airReleaseListener->onTouchesBegan = [&](const std::vector<Touch*>& touches, Event *unused_event){
		auto target = static_cast<Layer*>(unused_event->getCurrentTarget());
		for (auto &touch : touches){
			Point currentpos = target->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView()));
			airPartlemap[touch->getID()] = AirPartle::create();
			this->addCrashTest(touch->getID());
			this->addChild(airPartlemap[touch->getID()]);
			airPartlemap[touch->getID()]->setID(touch->getID());
			airPartlemap[touch->getID()]->initAir();
			airPartlemap[touch->getID()]->setPosition(currentpos);
		}
	};

	airReleaseListener->onTouchesMoved = [&](const std::vector<Touch*>& touches, Event *unused_event){
		auto target = static_cast<Layer*>(unused_event->getCurrentTarget());
		for (auto &touch : touches){
			Point currentpos = target->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView()));
			Point previouspos = target->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getPreviousLocationInView()));
			int step = currentpos.getDistance(previouspos) / 6;
			airPartlemap[touch->getID()]->setmoveSpeed(step);
			airPartlemap[touch->getID()]->getMoveBridge(currentpos-previouspos);
		}
	};
	airReleaseListener->onTouchesEnded = [&](const std::vector<Touch*>& touches, Event *unused_event){
		for (auto &touch : touches){
			airPartlemap[touch->getID()]->stopSystem();
			airPartlemap.erase(touch->getID());
		}
	};
	airReleaseListener->onTouchesCancelled = [](const std::vector<Touch*>& touches, Event *unused_event){
	};

	_layer->getEventDispatcher()->addEventListenerWithSceneGraphPriority(airReleaseListener, _layer);
	//airReleaseListener->setEnabled(false);
}

bool Air::init(){
	if (!Node::init()){
		return false;
	}
	setPosition(Point(0, 0));
	return true;
}

void Air::addCrashTest(int airID){
	for (Fire* fire : fires){
		fire->initContactParticleNumber(airID);
	}
}

void Air::resetAir(int airID){
	for (Fire* fire : fires){
		fire->initContactParticleNumber(airID);
	}
}

void Air::check(int ID, Point pos, float size){
	for (Fire* fire : fires){
		if (fire->getPosition().getDistance(pos) < fire->getBindingSprite()->getContentSize().height*(fire->getBindingSprite()->getScale())){
			fire->addContactParticleNumber(ID);
		}
	}
}

void Air::checkCrash(Sprite* sprite){
	fires.pushBack(Fire::create());
	fires.back()->bindingSprite(sprite);
	BoundingFire[sprite] = fires.back();
	this->addChild(fires.back());
	float radios = sprite->getBoundingBox().size.height / 2;
	fires.back()->setStartSizeVar(radios);
	fires.back()->setStartSize(radios);
}

long Air::getContactAirParticleNum(Sprite* sprite){
	Fire* result = BoundingFire.at(sprite);
	if (result != nullptr)return result->getContactParticleNumber();
	else return 0;
}

Point Air::getPosition(){
	Point pos = Node::getPosition();
	return this->convertToNodeSpace(pos);
	//return pos;
}

void Air::setPosition(const Point& position){
	Node::setPosition(position);
	//Node::setPosition(this->convertToNodeSpace(position));
}